# -*- coding: utf-8 -*-
# @Time    : 2023/9/20 10:30
# @Author  : Jonny
# @File    : LuckMqMain.py
# @Describe: MQ钉钉消息提醒入口

from flask import Flask,request
from apscheduler.schedulers.background import BackgroundScheduler
from flask_basicauth import BasicAuth
import json
import os
from logging.handlers import TimedRotatingFileHandler
import logging
import time
from LuckMqConstant import LuckMqConstant
from LuckMqService import LuckMqService
from LuckMqQueueService import LuckMqQueueService
from LuckMqMsgService import LuckMqMsgService

scheduler = BackgroundScheduler()
app = Flask(__name__)
try:
    app.json.ensure_ascii = False  # 解决中文乱码问题
except Exception:
    app.ensure_ascii = False  # 解决中文乱码问题

# 获取当前脚本的路径
script_dir = os.path.dirname(os.path.abspath(__file__))  # 项目工程路径/app
# 如果works/logs文件夹不存在则创建
if not os.path.exists(os.path.join(script_dir, LuckMqConstant.LOG_DIR)):
    os.makedirs(os.path.join(script_dir, LuckMqConstant.LOG_DIR))
app.config['LOG_FILE'] = os.path.join(script_dir, LuckMqConstant.LOG_DIR, LuckMqConstant.LOG_FILE)  # 修改log文件路径到logs文件夹下
app.config['LOG_LEVEL'] = logging.INFO
app.config['LOG_FORMAT'] = '%(asctime)s %(levelname)s: %(message)s'

# 配置全局日志
LOG_FILE = app.config['LOG_FILE']
LOG_LEVEL = app.config['LOG_LEVEL']
LOG_FORMAT = app.config['LOG_FORMAT']

# 设置日志格式
formatter = logging.Formatter(LOG_FORMAT)

# 设置日志处理器，按天生成日志文件
handler = TimedRotatingFileHandler(LOG_FILE, when="midnight", interval=1, backupCount=3)  # 每天生成一个新的日志文件，保留最近3天的日志文件
handler.setFormatter(formatter)  # 设置日志格式
handler.setLevel(LOG_LEVEL)  # 设置日志级别

# 创建并配置logger对象
logger = logging.getLogger()  # 获取root logger对象
logger.setLevel(LOG_LEVEL)  # 设置root logger的日志级别
logger.addHandler(handler)  # 添加handler到root logger对象中
logger.info('Start of the program')  # 输出一条info级别的日志，用于测试日志功能是否正常开启

global config

# 从环境变量中读取参数
server_port = os.getenv("SERVER_PORT")
if server_port is not None and server_port != '':
    config = {
        "server_port": int(server_port),
        "scheduler_seconds": int(os.getenv("SCHEDULER_SECONDS")),

        "agent_id": os.getenv("AGENT_ID"),
        "app_key": os.getenv("APP_KEY"),
        "app_secret": os.getenv("APP_SECRET"),

        "dingtalk_app_key": os.getenv("DINGTALK_APP_KEY"),
        "dingtalk_app_secret": os.getenv("DINGTALK_APP_SECRET"),
        "dingtalk_user_filter_type": os.getenv("DINGTALK_USER_FILTER_TYPE"),
        "dingtalk_url": os.getenv("DINGTALK_URL"),
        "dingtalk_url_basic_auth1": os.getenv("DINGTALK_URL_BASIC_AUTH1"),
        "dingtalk_url_basic_auth2": os.getenv("DINGTALK_URL_BASIC_AUTH2"),

        "mq_rpc_api_basic_auth1": os.getenv("MQ_RPC_API_BASIC_AUTH1"),
        "mq_rpc_api_basic_auth2": os.getenv("MQ_RPC_API_BASIC_AUTH2")
    }

    # 认证鉴权
    basic_auth1 = os.getenv("BASIC_AUTH1")
    if basic_auth1 is None or len(basic_auth1) <= 0:
        basic_auth1 = "admin"
    config["basic_auth1"] = basic_auth1

    basic_auth2 = os.getenv("BASIC_AUTH2")
    if basic_auth2 is None or len(basic_auth2) <= 0:
        basic_auth2 = "luckserver"
    config["basic_auth2"] = basic_auth2

    # 读取环境变量中机器人消息类型
    dingtalk_robot_msg_type = os.getenv("DINGTALK_ROBOT_MSG_TYPE")
    if dingtalk_robot_msg_type is None or len(dingtalk_robot_msg_type) <= 0:
        dingtalk_robot_msg_type = "text"
    config["dingtalk_robot_msg_type"] = dingtalk_robot_msg_type

    # 读取环境变量中的钉钉机器人信息放入集合中，以供服务层使用
    dingtalk_robot_list = []
    for i in range(1, 4):
        dingtalk_robot_secret_ = os.getenv(f'DINGTALK_ROBOT_SECRET_{i}')
        dingtalk_robot_access_token_ = os.getenv(f'DINGTALK_ROBOT_ACCESS_TOKEN_{i}')
        if dingtalk_robot_secret_ is not None and dingtalk_robot_secret_ != '' and dingtalk_robot_access_token_ is not None and dingtalk_robot_access_token_ != '':
            dingtalk_robot_list.append({
                "dingtalk_robot_secret": dingtalk_robot_secret_,
                "dingtalk_robot_access_token": dingtalk_robot_access_token_
            })
    config["dingtalk_robot_list"] = dingtalk_robot_list

    # 读取环境变量中的mq 翻译信息放入集合中，以供服务层使用
    mq_application_list = []
    for i in range(1, 51):
        mq_application_ = os.getenv(f'MQ_APPLICATION_{i}')
        if mq_application_ is not None and mq_application_ != '' and len(mq_application_.split('/')) >= 3:
            mq_application_list.append({
                "label": mq_application_.split('/')[0],
                "name": mq_application_.split('/')[1],
                "userid": mq_application_.split('/')[2]
            })
    config["mq_application_list"] = mq_application_list

    # 读取环境变量中的mq 包含信息放入集合中，以供服务层使用
    mq_application_inclusions_list = []
    mq_application_inclusions_ = os.getenv('MQ_APPLICATION_INCLUSIONS')
    if mq_application_inclusions_ is not None and mq_application_inclusions_ != '':
        mq_application_inclusions_list += mq_application_inclusions_.split('/')
    # 判断是否有%号，没有就默认在两边增加
    mq_application_inclusions_list1 = ["%" + item + "%" if "%" not in item else item for item in mq_application_inclusions_list]
    config["mq_application_inclusions_list"] = mq_application_inclusions_list1

    # 读取环境变量中的mq 不包含信息放入集合中，以供服务层使用
    mq_application_exclusions_list = []
    mq_application_exclusions_ = os.getenv('MQ_APPLICATION_EXCLUSIONS')
    if mq_application_exclusions_ is not None and mq_application_exclusions_ != '':
        mq_application_exclusions_list += mq_application_exclusions_.split('/')
    # 判断是否有%号，没有就默认在两边增加
    mq_application_exclusions_list1 = ["%" + item + "%" if "%" not in item else item for item in mq_application_exclusions_list]
    config["mq_application_exclusions_list"] = mq_application_exclusions_list1

    # 读取环境变量中的rpc信息放入mq集合中，以供服务层使用
    mq_rpc_api_list = []
    for i in range(1, 11):
        mq_rpc_api_ = os.getenv(f'MQ_RPC_API_{i}')
        if mq_rpc_api_ is not None and mq_rpc_api_ != '':
            mq_rpc_api_list.append({
                "mq_rpc_api": mq_rpc_api_
            })
    config["mq_rpc_api_list"] = mq_rpc_api_list
else:
    filename = os.path.join(script_dir, 'works/LuckMqConfig.json')
    with open(filename, "r", encoding="utf-8") as fp:
        json_str = fp.read().strip()
        if json_str is not None and len(json_str) > 0:
            config = json.loads(json_str)

            # 认证鉴权
            basic_auth1 = config["basic_auth1"]
            if basic_auth1 is None or len(basic_auth1) <= 0:
                basic_auth1 = "admin"
            config["basic_auth1"] = basic_auth1

            basic_auth2 = config["basic_auth2"]
            if basic_auth2 is None or len(basic_auth2) <= 0:
                basic_auth2 = "luckserver"
            config["basic_auth2"] = basic_auth2

            # 读取环境变量中机器人消息类型
            dingtalk_robot_msg_type = config["dingtalk_robot_msg_type"]
            if dingtalk_robot_msg_type is None or len(dingtalk_robot_msg_type) <= 0:
                dingtalk_robot_msg_type = "text"
            config["dingtalk_robot_msg_type"] = dingtalk_robot_msg_type

            # 读取环境变量中的钉钉机器人信息放入集合中，以供服务层使用
            dingtalk_robot_list = []
            for i in range(1, 4):
                dingtalk_robot_secret_ = config[f'dingtalk_robot_secret_{i}']
                dingtalk_robot_access_token_ = config[f'dingtalk_robot_access_token_{i}']
                if dingtalk_robot_secret_ is not None and dingtalk_robot_secret_ != '' and dingtalk_robot_access_token_ is not None and dingtalk_robot_access_token_ != '':
                    dingtalk_robot_list.append({
                        "dingtalk_robot_secret": dingtalk_robot_secret_,
                        "dingtalk_robot_access_token": dingtalk_robot_access_token_
                    })
            config["dingtalk_robot_list"] = dingtalk_robot_list

            # 读取环境变量中的mq 翻译信息放入集合中，以供服务层使用
            mq_application_list = []
            for i in range(1, 51):
                mq_application_ = config[f'mq_application_{i}']
                if mq_application_ is not None and mq_application_ != '' and len(mq_application_.split('/')) >= 3:
                    mq_application_list.append({
                        "label": mq_application_.split('/')[0],
                        "name": mq_application_.split('/')[1],
                        "userid": mq_application_.split('/')[2]
                    })
            config["mq_application_list"] = mq_application_list

            # 读取环境变量中的mq 包含信息放入集合中，以供服务层使用
            mq_application_inclusions_list = []
            mq_application_inclusions_ = config['mq_application_inclusions']
            if mq_application_inclusions_ is not None and mq_application_inclusions_ != '':
                mq_application_inclusions_list += mq_application_inclusions_.split('/')
            # 判断是否有%号，没有就默认在两边增加
            mq_application_inclusions_list1 = ["%" + item + "%" if "%" not in item else item for item in mq_application_inclusions_list]
            config["mq_application_inclusions_list"] = mq_application_inclusions_list1

            # 读取环境变量中的mq 不包含信息放入集合中，以供服务层使用
            mq_application_exclusions_list = []
            mq_application_exclusions_ = config['mq_application_exclusions']
            if mq_application_exclusions_ is not None and mq_application_exclusions_ != '':
                mq_application_exclusions_list += mq_application_exclusions_.split('/')
            # 判断是否有%号，没有就默认在两边增加
            mq_application_exclusions_list1 = ["%" + item + "%" if "%" not in item else item for item in mq_application_exclusions_list]
            config["mq_application_exclusions_list"] = mq_application_exclusions_list1

            # 读取环境变量中的rpc信息放入mq集合中，以供服务层使用
            mq_rpc_api_list = []
            for i in range(1, 11):
                mq_rpc_api_ = config[f'mq_rpc_api_{i}']
                if mq_rpc_api_ is not None and mq_rpc_api_ != '':
                    mq_rpc_api_list.append({
                        "mq_rpc_api": mq_rpc_api_
                    })
            config["mq_rpc_api_list"] = mq_rpc_api_list

# 基本认证鉴权
app.config['BASIC_AUTH_USERNAME'] = config["basic_auth1"]
app.config['BASIC_AUTH_PASSWORD'] = config["basic_auth2"]
app.config['BASIC_AUTH_FORCE'] = False  # 为True 就默认对所有 api 进行认证， 如果设置为 False， 那么可以通过 @basic_auth.required 对指定 api 进行认证。
basic_auth = BasicAuth(app)

# 检查MQ服务状态
@app.route('/')
@basic_auth.required
def index():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 查看MQ服务部署状态')

    return {
        "code": 1,
        "data": ["/", "/check"
            , "/queue/createTable", "/queue/deleteTable", "/queue/dropTable", "/queue/readTableData"
            , "/msg/createTable", "/msg/deleteTable", "/msg/dropTable", "/msg/readTableData"
                 ],
        "msg": "MQ监控服务部署成功"
    }


# 创建表
@app.route('/queue/createTable')
@basic_auth.required
def queue_create_table():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 创建表')

    server_service = LuckMqQueueService(config)
    return server_service.create_table()


# 清空数据
@app.route('/queue/deleteTable')
def queue_delete_table():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 清空数据')

    server_service = LuckMqQueueService(config)
    return server_service.delete_table()


# 删除表
@app.route('/queue/dropTable')
@basic_auth.required
def queue_drop_table():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 删除表')

    server_service = LuckMqQueueService(config)
    return server_service.drop_table()


# 读取表数据
@app.route('/queue/readTableData')
@basic_auth.required
def queue_read_table_data():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 读取表数据')
    tablename = request.args.get('tablename')
    if tablename is None:
        tablename = "luck_mq_queue"
    parameters = {
        "tablename": tablename
    }
    server_service = LuckMqQueueService(config)
    return server_service.read_table_data(parameters)



# 创建表
@app.route('/msg/createTable')
@basic_auth.required
def msg_create_table():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 创建表')

    server_service = LuckMqMsgService(config)
    return server_service.create_table()


# 清空数据
@app.route('/msg/deleteTable')
def msg_delete_table():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 清空数据')

    server_service = LuckMqMsgService(config)
    return server_service.delete_table()


# 删除表
@app.route('/msg/dropTable')
@basic_auth.required
def msg_drop_table():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 删除表')

    server_service = LuckMqMsgService(config)
    return server_service.drop_table()


# 读取表数据
@app.route('/msg/readTableData')
@basic_auth.required
def msg_read_table_data():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 读取表数据')
    tablename = request.args.get('tablename')
    if tablename is None:
        tablename = "luck_mq_msg"
    parameters = {
        "tablename": tablename
    }
    server_service = LuckMqMsgService(config)
    return server_service.read_table_data(parameters)

# 手动巡检
@app.route('/check')
@basic_auth.required
def check():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 开始MQ手动巡检')

    mq_service = LuckMqService(config)
    mq_service.read_queues()

    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 结束MQ手动巡检')

    return {
        "code": 1,
        "msg": "手动巡检成功"
    }


# 发送消息
def job_send_msg():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 开始发送消息')

    mq_service = LuckMqService(config)
    mq_service.send_msg()

    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 结束发送消息')

# 采集数据
def job_read_data():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 开始MQ巡检')

    mq_service = LuckMqService(config)
    mq_service.read_queues()

    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 结束MQ巡检')

# 删除七天前队列
def job_delete_seven_days_ago():
    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 开始删除七天前队列')

    mq_service = LuckMqQueueService(config)
    mq_service.delete_seven_days_ago()

    print(f'小程序 于 {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))} 结束删除七天前队列')

# 添加定时任务
scheduler.add_job(job_read_data, 'interval', seconds=config["scheduler_seconds"])
# scheduler.add_job(job_send_msg, 'interval', seconds=config["scheduler_seconds"])
# scheduler.add_job(job_delete_seven_days_ago, 'cron', hour='12')
scheduler.start()

if __name__ == '__main__':
    mq_service = LuckMqQueueService(config)
    mq_service.delete_table()
    msg_service = LuckMqMsgService(config)
    msg_service.delete_table()

    app.run(debug=False, use_reloader=False, host='0.0.0.0', port=config["server_port"])
